package org.opensuse.bs.ui;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Set;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.w3c.dom.Document;

public class OSC {
	/*Write modified xml dom obj to a temp file*/
	public static File toFile(Document doc, String filename) throws Exception {
		File file = File.createTempFile(filename, "bsplugin");
		DOMSource domSource = new DOMSource(doc);
		FileOutputStream out = new FileOutputStream(file);
		StreamResult sr = new StreamResult(out);
		TransformerFactory tfactory = TransformerFactory.newInstance();
		Transformer tf = tfactory.newTransformer();
		String encoding = doc.getInputEncoding();
		if(encoding != null) {
			tf.setOutputProperty(OutputKeys.ENCODING, encoding);
		}
		tf.setOutputProperty(OutputKeys.INDENT, "true");
		tf.transform(domSource, sr);
		return file;
	}
	
	/*Execute an osc command and return a xml dom obj as the result*/
	public static Document toXML(String cmd) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Vector<String> result = OSC.run(cmd);
		if(result.isEmpty()) {
			return null;
		}
		StringBuffer buf = new StringBuffer();
		for(String line : result) {
			buf.append(line);
		}
		ByteArrayInputStream in = new ByteArrayInputStream(buf.toString().getBytes());
		Document doc = builder.parse(in);
		in.close();
		doc.getDocumentElement().normalize();
		return doc;
	}
	
	/*Execute an osc command*/
	public static Vector<String> run(String cmd) {
		return run(cmd, null, null);
	}
	
	/*Execute an osc command in a given directory*/
	public static Vector<String> run(String cmd, String[] envp, File dir) {
		Vector<String> result = new Vector<String>();
		try {
			String command = "osc -A "+BSUIPlugin.getDefault().getApiurl()+" "+cmd;
			Process proc = Runtime.getRuntime().exec(command, envp, dir);
			InputStreamReader in = new InputStreamReader(proc.getInputStream());
			BufferedReader input = new BufferedReader(in);
			InputStreamReader err = new InputStreamReader(proc.getErrorStream());
			BufferedReader error = new BufferedReader(err);
			int status = proc.waitFor();
			String line;
			if(status == 0) {
				while((line = input.readLine()) != null) {
					if(line.trim().length() == 0)
						continue;
					result.add(line.trim());
				}
				input.close(); error.close();
				return result;
			}
			else {
				final StringBuffer buf = new StringBuffer();
				while((line = error.readLine())!=null) {
					buf.append(line+System.getProperty("line.separator"));
				}
				input.close(); error.close();
				throw new Exception(buf.toString());
			}
		}catch (Exception e) {
			if(e instanceof IOException || e instanceof InterruptedException) {
				e.printStackTrace();
			}
			else {
				final Exception exception = e;
				Display display = BSUIPlugin.getDefault().getWorkbench().getDisplay();
				display.asyncExec(new Runnable() {
					public void run() {
						MessageDialog.openError(null, "osc error!", exception.getMessage());
					}
				});
			}
		}
		return result;
	}
	
	/*Write contents to .oscrc file*/
	public static void writeback(HashMap<String, HashMap<String, String>> sections) throws IOException {
		// write content of sections back to ~/.oscrc
		String home = System.getProperty("user.home");
		File oscrc = BSUIPlugin.getDefault().getOscrc();
		if(oscrc.exists()) {
			File file = new File(home+"/.oscrc~");
			oscrc.renameTo(file);
			oscrc = new File(home+"/.oscrc");
		}
		oscrc.createNewFile();
		FileWriter out = new FileWriter(oscrc);
		BufferedWriter output = new BufferedWriter(out);
		Set<String> keys = sections.keySet();
		for(String key : keys) {
			output.write("["+key+"]");
			output.newLine();
			HashMap<String, String> section = sections.get(key);
			Set<String> key1s = section.keySet();
			for(String key1 : key1s) {
				output.write(key1+" = "+section.get(key1));
				output.newLine();
			}
		}
		output.close();
	}
}
